package com.tang.websocket.v1.session;

import com.tang.websocket.v1.Converter;
import com.tang.websocket.v1.ConverterRegistry;
import com.tang.websocket.v1.message.TextMessage;
import com.tang.websocket.v1.message.WebSocketMessage;
import com.tang.websocket.v1.message.PingMessage;
import com.tang.websocket.v1.message.PongMessage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.ResolvableType;

import javax.websocket.Session;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.Map;
import java.util.Objects;

/**
 * @author Tang
 * @classname StandardWebSocketSession
 * @description [  ]
 * @date 2022/11/28 15:19
 */
@Slf4j
public class StandardWebSocketSession extends AbstractWebSocketSession<Session> {

    private final ConverterRegistry converterRegistry;

    public StandardWebSocketSession(ConverterRegistry converterRegistry) {
        this.converterRegistry = converterRegistry;
    }

    @Override
    public String getId() {
        return this.idGenerator.generateId().toString();
    }

    @Override
    protected void handlerMsg(WebSocketMessage<?> message) {
        Class<?> rawClass = ResolvableType.forClass(message.getClass())
                .getGeneric(0)
                .getRawClass();
        Converter<Object, Object> converter = converterRegistry.selectConverter(rawClass, String.class);
        if (Objects.nonNull(converter)) {
            String txtMsg = converter.convert(message.getPayLoad()).toString();
            handlerMsg(new TextMessage(txtMsg));
        }
        log.info("无法解析的消息：{}",message.toString());
    }

    @Override
    protected void handlerMsg(PongMessage message) {
        TextMessage textMessage = new TextMessage(message.toString());
        handlerMsg(textMessage);
    }

    @Override
    protected void handlerMsg(PingMessage message) {
        TextMessage textMessage = new TextMessage(message.toString());
        handlerMsg(textMessage);
    }

    @Override
    protected void handlerMsg(TextMessage message) {
        if (isOpen()) {
            try {
                getNativeSession(Session.class)
                        .getBasicRemote()
                        .sendText(message.getPayLoad());
            } catch (Exception e) {
                e.printStackTrace();
            }
            return;
        }
        log.info("被丢弃的离线消息：{}",message.getPayLoad());
    }

    @Override
    public Map<String, Object> getAttributes() {
        return getNativeSession(Session.class).getUserProperties();
    }

    @Override
    public Map<String, String> getPathParameters() {
        return getNativeSession(Session.class).getPathParameters();
    }

    @Override
    public InetSocketAddress getLocalAddress() {
        return null;
    }

    @Override
    public InetSocketAddress getRemoteAddress() {
        return null;
    }

    @Override
    public boolean isOpen() {
        return getNativeSession(Session.class).isOpen();
    }

    @Override
    public void close() throws IOException {
        if (isOpen()) {
            getNativeSession(Session.class).close();
        }
    }

}
